package com.fjzx.androidframe.network.downloader;


import com.fjzx.androidframe.network.ApiFactory;
import com.fjzx.androidframe.network.callback.DownloadProgressListener;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;

import bolts.Continuation;
import bolts.Task;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.Interceptor;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;

/**
 * 文件下载器
 *
 * @author xiongyongcong
 */
public class XDownloader {
    public static void download(String url, String savePath, DownloadProgressListener listener) {
        // 添加拦截器，拦截Response，添加自定义带Progress的ResponseBody
        OkHttpClient client = ApiFactory.createOkHttpClientBuilder((Interceptor) chain -> {
            Response response = chain.proceed(chain.request());
            return response.newBuilder().body(new ProgressResponseBody(response.body(), listener)).build();
        }).build();
        final Request request = new Request.Builder().url(url).build();
        Call call = client.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onResponse(Call call, Response response) throws IOException {
                // 保存文件
                saveFile(response.body(), savePath, listener);
            }

            @Override
            public void onFailure(Call call, IOException e) {
                if (listener != null) {
                    listener.onError(e);
                }
            }
        });
    }

    /**
     * 保存文件
     *
     * @param responseBody 响应实体
     * @param savePath 保存路径
     * @param listener 进度回调
     */
    public static void saveFile(ResponseBody responseBody, String savePath, DownloadProgressListener listener) {
        Task.callInBackground(() -> {
            FileOutputStream fos = null;
            InputStream bodyStream = null;
            try {
                fos = new FileOutputStream(savePath);
                bodyStream = responseBody.byteStream();
                byte[] buff = new byte[1024];
                int readByte;
                while ((readByte = bodyStream.read(buff)) != -1) {
                    fos.write(buff, 0, readByte);
                }
                fos.flush();
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            } finally {
                bodyStream.close();
                fos.close();
            }
            return true;
        }).continueWith((Continuation<Boolean, Void>) task -> {
            if (listener != null) {
                listener.onSuccess(savePath);
            }
            return null;
        }, Task.UI_THREAD_EXECUTOR);
    }
}
